package tv.acgn.advertisement.servicebase.vo;

import java.time.LocalDateTime;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import tv.acgn.advertisement.servicebase.advice.GlobalExceptionResolverAdvice;

/**
 * @program: advertisement
 * @description: 通用 服务调用 请求响应类
 * @author: junG
 * @create: 2019-04-22 00:34
 **/

@Data
@Accessors(chain = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class CommonResponse<T> {

    /**
     * <h2>全局请求识别码</h2>
     * 用于在分布式系统中追踪请求链路 记录请求日志
     *
     * 此识别码在全部请求中应为唯一
     * 或者至少保证在某一较长时间段唯一
     */
    private String requestId;

    /**
     * <h2>返回调用状态码</h2>
     * 用于标明调用的一些状态
     * 默认0 标明请求成功
     * 注意 此并不要求与HTTP请求状态码一定一致
     *
     * 但一些常用的错误行为可以定义为与HTTP状态码一致
     */
    private Integer code;

    /**
     * <h2>返回消息</h2>
     * 非业务流程中的消息
     * 而是调用链路中其他组件可能设置的 通知链路上下层的消息
     * 如 {@link GlobalExceptionResolverAdvice}
     * 设置的请求错误消息
     * 业务流程中的消息 在#data中设置
     */
    private String message;

    /**
     * <h2>返回消息识别码</h2>
     * 返回消息的标识码
     * 可用于其他系统从外部资源库加载返回信息
     * 以便国际化
     */
    private String messageCode;

    /**
     * <h2>返回 此次调用是否成功</h2>
     * 如果为true -> 说明调用成功 则调用方处理 #data 的数据
     * 如果为false -> 说明调用失败 则调用方处理 #exception 的数据
     */
    private Boolean success;

    /**
     * <h2>调用模块</h2>
     *
     * 分布式系统中标明哪个模块进行此次调用
     */
    private String model;

    /**
     * <h2>用户身份码</h2>
     */
    private String userId;

    /**
     * <h2>返回数据体</h2>
     *
     * 调用成功 设置此数据体
     */
    private T data;

    /**
     * <h2>返回异常</h2>
     * 调用失败 设置异常内容体
     */
    private T exception;

    /**
     * 本次调用结束时间
     */
    private LocalDateTime endTime;

    public CommonResponse(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}
